{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Environment Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pandas : 0.20.3\n",
      "numpy : 1.13.1\n",
      "matplotlib : 2.0.2\n",
      "seaborn : 0.7.1\n",
      "sklearn : 0.18.2\n",
      "imblearn : 0.2.1\n"
     ]
    }
   ],
   "source": [
    "# import relevant modules\n",
    "%matplotlib inline\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import seaborn as sns\n",
    "import sklearn\n",
    "import imblearn\n",
    "\n",
    "# Ignore warnings\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "# Settings\n",
    "pd.set_option('display.max_columns', None)\n",
    "np.set_printoptions(threshold=np.nan)\n",
    "np.set_printoptions(precision=3)\n",
    "sns.set(style=\"darkgrid\")\n",
    "plt.rcParams['axes.labelsize'] = 14\n",
    "plt.rcParams['xtick.labelsize'] = 12\n",
    "plt.rcParams['ytick.labelsize'] = 12\n",
    "\n",
    "print(\"pandas : {0}\".format(pd.__version__))\n",
    "print(\"numpy : {0}\".format(np.__version__))\n",
    "print(\"matplotlib : {0}\".format(matplotlib.__version__))\n",
    "print(\"seaborn : {0}\".format(sns.__version__))\n",
    "print(\"sklearn : {0}\".format(sklearn.__version__))\n",
    "print(\"imblearn : {0}\".format(imblearn.__version__))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "code_folding": [],
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Dataset field names\n",
    "datacols = [\"duration\",\"protocol_type\",\"service\",\"flag\",\"src_bytes\",\n",
    "    \"dst_bytes\",\"land\",\"wrong_fragment\",\"urgent\",\"hot\",\"num_failed_logins\",\n",
    "    \"logged_in\",\"num_compromised\",\"root_shell\",\"su_attempted\",\"num_root\",\n",
    "    \"num_file_creations\",\"num_shells\",\"num_access_files\",\"num_outbound_cmds\",\n",
    "    \"is_host_login\",\"is_guest_login\",\"count\",\"srv_count\",\"serror_rate\",\n",
    "    \"srv_serror_rate\",\"rerror_rate\",\"srv_rerror_rate\",\"same_srv_rate\",\n",
    "    \"diff_srv_rate\",\"srv_diff_host_rate\",\"dst_host_count\",\"dst_host_srv_count\",\n",
    "    \"dst_host_same_srv_rate\",\"dst_host_diff_srv_rate\",\"dst_host_same_src_port_rate\",\n",
    "    \"dst_host_srv_diff_host_rate\",\"dst_host_serror_rate\",\"dst_host_srv_serror_rate\",\n",
    "    \"dst_host_rerror_rate\",\"dst_host_srv_rerror_rate\",\"attack\", \"last_flag\"]\n",
    "\n",
    "# Load NSL_KDD train dataset\n",
    "dfkdd_train = pd.read_table(\"~/NID/NSL_KDD_dataset/KDDTrain.txt\", sep=\",\", names=datacols) # change path to where the dataset is located.\n",
    "dfkdd_train = dfkdd_train.iloc[:,:-1] # removes an unwanted extra field\n",
    "\n",
    "# Load NSL_KDD test dataset\n",
    "dfkdd_test = pd.read_table(\"~/NID/NSL_KDD_dataset/KDDTest.txt\", sep=\",\", names=datacols)\n",
    "dfkdd_test = dfkdd_test.iloc[:,:-1]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Train dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>duration</th>\n",
       "      <th>protocol_type</th>\n",
       "      <th>service</th>\n",
       "      <th>flag</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>land</th>\n",
       "      <th>wrong_fragment</th>\n",
       "      <th>urgent</th>\n",
       "      <th>hot</th>\n",
       "      <th>num_failed_logins</th>\n",
       "      <th>logged_in</th>\n",
       "      <th>num_compromised</th>\n",
       "      <th>root_shell</th>\n",
       "      <th>su_attempted</th>\n",
       "      <th>num_root</th>\n",
       "      <th>num_file_creations</th>\n",
       "      <th>num_shells</th>\n",
       "      <th>num_access_files</th>\n",
       "      <th>num_outbound_cmds</th>\n",
       "      <th>is_host_login</th>\n",
       "      <th>is_guest_login</th>\n",
       "      <th>count</th>\n",
       "      <th>srv_count</th>\n",
       "      <th>serror_rate</th>\n",
       "      <th>srv_serror_rate</th>\n",
       "      <th>rerror_rate</th>\n",
       "      <th>srv_rerror_rate</th>\n",
       "      <th>same_srv_rate</th>\n",
       "      <th>diff_srv_rate</th>\n",
       "      <th>srv_diff_host_rate</th>\n",
       "      <th>dst_host_count</th>\n",
       "      <th>dst_host_srv_count</th>\n",
       "      <th>dst_host_same_srv_rate</th>\n",
       "      <th>dst_host_diff_srv_rate</th>\n",
       "      <th>dst_host_same_src_port_rate</th>\n",
       "      <th>dst_host_srv_diff_host_rate</th>\n",
       "      <th>dst_host_serror_rate</th>\n",
       "      <th>dst_host_srv_serror_rate</th>\n",
       "      <th>dst_host_rerror_rate</th>\n",
       "      <th>dst_host_srv_rerror_rate</th>\n",
       "      <th>attack</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "      <td>491</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>150</td>\n",
       "      <td>25</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.0</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>udp</td>\n",
       "      <td>other</td>\n",
       "      <td>SF</td>\n",
       "      <td>146</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.08</td>\n",
       "      <td>0.15</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.88</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>S0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>123</td>\n",
       "      <td>6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>26</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   duration protocol_type   service flag  src_bytes  dst_bytes  land  \\\n",
       "0         0           tcp  ftp_data   SF        491          0     0   \n",
       "1         0           udp     other   SF        146          0     0   \n",
       "2         0           tcp   private   S0          0          0     0   \n",
       "\n",
       "   wrong_fragment  urgent  hot  num_failed_logins  logged_in  num_compromised  \\\n",
       "0               0       0    0                  0          0                0   \n",
       "1               0       0    0                  0          0                0   \n",
       "2               0       0    0                  0          0                0   \n",
       "\n",
       "   root_shell  su_attempted  num_root  num_file_creations  num_shells  \\\n",
       "0           0             0         0                   0           0   \n",
       "1           0             0         0                   0           0   \n",
       "2           0             0         0                   0           0   \n",
       "\n",
       "   num_access_files  num_outbound_cmds  is_host_login  is_guest_login  count  \\\n",
       "0                 0                  0              0               0      2   \n",
       "1                 0                  0              0               0     13   \n",
       "2                 0                  0              0               0    123   \n",
       "\n",
       "   srv_count  serror_rate  srv_serror_rate  rerror_rate  srv_rerror_rate  \\\n",
       "0          2          0.0              0.0          0.0              0.0   \n",
       "1          1          0.0              0.0          0.0              0.0   \n",
       "2          6          1.0              1.0          0.0              0.0   \n",
       "\n",
       "   same_srv_rate  diff_srv_rate  srv_diff_host_rate  dst_host_count  \\\n",
       "0           1.00           0.00                 0.0             150   \n",
       "1           0.08           0.15                 0.0             255   \n",
       "2           0.05           0.07                 0.0             255   \n",
       "\n",
       "   dst_host_srv_count  dst_host_same_srv_rate  dst_host_diff_srv_rate  \\\n",
       "0                  25                    0.17                    0.03   \n",
       "1                   1                    0.00                    0.60   \n",
       "2                  26                    0.10                    0.05   \n",
       "\n",
       "   dst_host_same_src_port_rate  dst_host_srv_diff_host_rate  \\\n",
       "0                         0.17                          0.0   \n",
       "1                         0.88                          0.0   \n",
       "2                         0.00                          0.0   \n",
       "\n",
       "   dst_host_serror_rate  dst_host_srv_serror_rate  dst_host_rerror_rate  \\\n",
       "0                   0.0                       0.0                  0.05   \n",
       "1                   0.0                       0.0                  0.00   \n",
       "2                   1.0                       1.0                  0.00   \n",
       "\n",
       "   dst_host_srv_rerror_rate   attack  \n",
       "0                       0.0   normal  \n",
       "1                       0.0   normal  \n",
       "2                       0.0  neptune  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train set dimension: 125973 rows, 42 columns\n"
     ]
    }
   ],
   "source": [
    "# View train data\n",
    "dfkdd_train.head(3)\n",
    "\n",
    "# train set dimension\n",
    "print('Train set dimension: {} rows, {} columns'.format(dfkdd_train.shape[0], dfkdd_train.shape[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Test dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>duration</th>\n",
       "      <th>protocol_type</th>\n",
       "      <th>service</th>\n",
       "      <th>flag</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>land</th>\n",
       "      <th>wrong_fragment</th>\n",
       "      <th>urgent</th>\n",
       "      <th>hot</th>\n",
       "      <th>num_failed_logins</th>\n",
       "      <th>logged_in</th>\n",
       "      <th>num_compromised</th>\n",
       "      <th>root_shell</th>\n",
       "      <th>su_attempted</th>\n",
       "      <th>num_root</th>\n",
       "      <th>num_file_creations</th>\n",
       "      <th>num_shells</th>\n",
       "      <th>num_access_files</th>\n",
       "      <th>num_outbound_cmds</th>\n",
       "      <th>is_host_login</th>\n",
       "      <th>is_guest_login</th>\n",
       "      <th>count</th>\n",
       "      <th>srv_count</th>\n",
       "      <th>serror_rate</th>\n",
       "      <th>srv_serror_rate</th>\n",
       "      <th>rerror_rate</th>\n",
       "      <th>srv_rerror_rate</th>\n",
       "      <th>same_srv_rate</th>\n",
       "      <th>diff_srv_rate</th>\n",
       "      <th>srv_diff_host_rate</th>\n",
       "      <th>dst_host_count</th>\n",
       "      <th>dst_host_srv_count</th>\n",
       "      <th>dst_host_same_srv_rate</th>\n",
       "      <th>dst_host_diff_srv_rate</th>\n",
       "      <th>dst_host_same_src_port_rate</th>\n",
       "      <th>dst_host_srv_diff_host_rate</th>\n",
       "      <th>dst_host_serror_rate</th>\n",
       "      <th>dst_host_srv_serror_rate</th>\n",
       "      <th>dst_host_rerror_rate</th>\n",
       "      <th>dst_host_srv_rerror_rate</th>\n",
       "      <th>attack</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>229</td>\n",
       "      <td>10</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.06</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>10</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.06</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>REJ</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>136</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.06</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.06</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>neptune</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "      <td>12983</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>134</td>\n",
       "      <td>86</td>\n",
       "      <td>0.61</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.61</td>\n",
       "      <td>0.02</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>normal</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   duration protocol_type   service flag  src_bytes  dst_bytes  land  \\\n",
       "0         0           tcp   private  REJ          0          0     0   \n",
       "1         0           tcp   private  REJ          0          0     0   \n",
       "2         2           tcp  ftp_data   SF      12983          0     0   \n",
       "\n",
       "   wrong_fragment  urgent  hot  num_failed_logins  logged_in  num_compromised  \\\n",
       "0               0       0    0                  0          0                0   \n",
       "1               0       0    0                  0          0                0   \n",
       "2               0       0    0                  0          0                0   \n",
       "\n",
       "   root_shell  su_attempted  num_root  num_file_creations  num_shells  \\\n",
       "0           0             0         0                   0           0   \n",
       "1           0             0         0                   0           0   \n",
       "2           0             0         0                   0           0   \n",
       "\n",
       "   num_access_files  num_outbound_cmds  is_host_login  is_guest_login  count  \\\n",
       "0                 0                  0              0               0    229   \n",
       "1                 0                  0              0               0    136   \n",
       "2                 0                  0              0               0      1   \n",
       "\n",
       "   srv_count  serror_rate  srv_serror_rate  rerror_rate  srv_rerror_rate  \\\n",
       "0         10          0.0              0.0          1.0              1.0   \n",
       "1          1          0.0              0.0          1.0              1.0   \n",
       "2          1          0.0              0.0          0.0              0.0   \n",
       "\n",
       "   same_srv_rate  diff_srv_rate  srv_diff_host_rate  dst_host_count  \\\n",
       "0           0.04           0.06                 0.0             255   \n",
       "1           0.01           0.06                 0.0             255   \n",
       "2           1.00           0.00                 0.0             134   \n",
       "\n",
       "   dst_host_srv_count  dst_host_same_srv_rate  dst_host_diff_srv_rate  \\\n",
       "0                  10                    0.04                    0.06   \n",
       "1                   1                    0.00                    0.06   \n",
       "2                  86                    0.61                    0.04   \n",
       "\n",
       "   dst_host_same_src_port_rate  dst_host_srv_diff_host_rate  \\\n",
       "0                         0.00                         0.00   \n",
       "1                         0.00                         0.00   \n",
       "2                         0.61                         0.02   \n",
       "\n",
       "   dst_host_serror_rate  dst_host_srv_serror_rate  dst_host_rerror_rate  \\\n",
       "0                   0.0                       0.0                   1.0   \n",
       "1                   0.0                       0.0                   1.0   \n",
       "2                   0.0                       0.0                   0.0   \n",
       "\n",
       "   dst_host_srv_rerror_rate   attack  \n",
       "0                       1.0  neptune  \n",
       "1                       1.0  neptune  \n",
       "2                       0.0   normal  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test set dimension: 22544 rows, 42 columns\n"
     ]
    }
   ],
   "source": [
    "# View test data\n",
    "dfkdd_test.head(3)\n",
    "\n",
    "# test set dimension\n",
    "print('Test set dimension: {} rows, {} columns'.format(dfkdd_test.shape[0], dfkdd_test.shape[1]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data Preprocessing"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Map attack field to attack class \n",
    "NSL-KDD dataset has 42 attributes for each connection record including class label containing attack types. The attack types are categorized into four attack classes as described by Mahbod Tavallaee et al. in [_A Detailed analysis of the KDD CUP 99 Data Set_](http://www.ee.ryerson.ca/~bagheri/papers/cisda.pdf) as:\n",
    "1. **Denial of Service (DoS)**: is an attack in which an adversary directed a deluge of traffic requests to a system in order to make the computing or memory resource too busy or too full to handle legitimate requests and in the process, denies legitimate users access to a machine.\n",
    "2. **Probing Attack (Probe)**: probing network of computers to gather information to be used to compromise its security controls. \n",
    "3. **User to Root Attack (U2R)**: a class of exploit in which the adversary starts out with access to a normal user account on the system (gained either by sniffing passwords, a dictionary attack, or social engineering) and is able to exploit some vulnerability to gain root access to the system. \n",
    "4. **Remote to Local Attack (R2L)**: occurs when an attacker who has the ability to send packets to a machine over a network but who does not have an account on that machine exploits some vulnerability to gain local access as a user of that machine. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "code_folding": [],
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "mapping = {'ipsweep': 'Probe','satan': 'Probe','nmap': 'Probe','portsweep': 'Probe','saint': 'Probe','mscan': 'Probe',\n",
    "        'teardrop': 'DoS','pod': 'DoS','land': 'DoS','back': 'DoS','neptune': 'DoS','smurf': 'DoS','mailbomb': 'DoS',\n",
    "        'udpstorm': 'DoS','apache2': 'DoS','processtable': 'DoS',\n",
    "        'perl': 'U2R','loadmodule': 'U2R','rootkit': 'U2R','buffer_overflow': 'U2R','xterm': 'U2R','ps': 'U2R',\n",
    "        'sqlattack': 'U2R','httptunnel': 'U2R',\n",
    "        'ftp_write': 'R2L','phf': 'R2L','guess_passwd': 'R2L','warezmaster': 'R2L','warezclient': 'R2L','imap': 'R2L',\n",
    "        'spy': 'R2L','multihop': 'R2L','named': 'R2L','snmpguess': 'R2L','worm': 'R2L','snmpgetattack': 'R2L',\n",
    "        'xsnoop': 'R2L','xlock': 'R2L','sendmail': 'R2L',\n",
    "        'normal': 'Normal'\n",
    "        }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Apply attack class mappings to the dataset\n",
    "dfkdd_train['attack_class'] = dfkdd_train['attack'].apply(lambda v: mapping[v])\n",
    "dfkdd_test['attack_class'] = dfkdd_test['attack'].apply(lambda v: mapping[v])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Drop attack field from both train and test data\n",
    "dfkdd_train.drop(['attack'], axis=1, inplace=True)\n",
    "dfkdd_test.drop(['attack'], axis=1, inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>duration</th>\n",
       "      <th>protocol_type</th>\n",
       "      <th>service</th>\n",
       "      <th>flag</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>land</th>\n",
       "      <th>wrong_fragment</th>\n",
       "      <th>urgent</th>\n",
       "      <th>hot</th>\n",
       "      <th>num_failed_logins</th>\n",
       "      <th>logged_in</th>\n",
       "      <th>num_compromised</th>\n",
       "      <th>root_shell</th>\n",
       "      <th>su_attempted</th>\n",
       "      <th>num_root</th>\n",
       "      <th>num_file_creations</th>\n",
       "      <th>num_shells</th>\n",
       "      <th>num_access_files</th>\n",
       "      <th>num_outbound_cmds</th>\n",
       "      <th>is_host_login</th>\n",
       "      <th>is_guest_login</th>\n",
       "      <th>count</th>\n",
       "      <th>srv_count</th>\n",
       "      <th>serror_rate</th>\n",
       "      <th>srv_serror_rate</th>\n",
       "      <th>rerror_rate</th>\n",
       "      <th>srv_rerror_rate</th>\n",
       "      <th>same_srv_rate</th>\n",
       "      <th>diff_srv_rate</th>\n",
       "      <th>srv_diff_host_rate</th>\n",
       "      <th>dst_host_count</th>\n",
       "      <th>dst_host_srv_count</th>\n",
       "      <th>dst_host_same_srv_rate</th>\n",
       "      <th>dst_host_diff_srv_rate</th>\n",
       "      <th>dst_host_same_src_port_rate</th>\n",
       "      <th>dst_host_srv_diff_host_rate</th>\n",
       "      <th>dst_host_serror_rate</th>\n",
       "      <th>dst_host_srv_serror_rate</th>\n",
       "      <th>dst_host_rerror_rate</th>\n",
       "      <th>dst_host_srv_rerror_rate</th>\n",
       "      <th>attack_class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "      <td>491</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>150</td>\n",
       "      <td>25</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.0</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>udp</td>\n",
       "      <td>other</td>\n",
       "      <td>SF</td>\n",
       "      <td>146</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.08</td>\n",
       "      <td>0.15</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.88</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>S0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>123</td>\n",
       "      <td>6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.0</td>\n",
       "      <td>255</td>\n",
       "      <td>26</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.0</td>\n",
       "      <td>DoS</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   duration protocol_type   service flag  src_bytes  dst_bytes  land  \\\n",
       "0         0           tcp  ftp_data   SF        491          0     0   \n",
       "1         0           udp     other   SF        146          0     0   \n",
       "2         0           tcp   private   S0          0          0     0   \n",
       "\n",
       "   wrong_fragment  urgent  hot  num_failed_logins  logged_in  num_compromised  \\\n",
       "0               0       0    0                  0          0                0   \n",
       "1               0       0    0                  0          0                0   \n",
       "2               0       0    0                  0          0                0   \n",
       "\n",
       "   root_shell  su_attempted  num_root  num_file_creations  num_shells  \\\n",
       "0           0             0         0                   0           0   \n",
       "1           0             0         0                   0           0   \n",
       "2           0             0         0                   0           0   \n",
       "\n",
       "   num_access_files  num_outbound_cmds  is_host_login  is_guest_login  count  \\\n",
       "0                 0                  0              0               0      2   \n",
       "1                 0                  0              0               0     13   \n",
       "2                 0                  0              0               0    123   \n",
       "\n",
       "   srv_count  serror_rate  srv_serror_rate  rerror_rate  srv_rerror_rate  \\\n",
       "0          2          0.0              0.0          0.0              0.0   \n",
       "1          1          0.0              0.0          0.0              0.0   \n",
       "2          6          1.0              1.0          0.0              0.0   \n",
       "\n",
       "   same_srv_rate  diff_srv_rate  srv_diff_host_rate  dst_host_count  \\\n",
       "0           1.00           0.00                 0.0             150   \n",
       "1           0.08           0.15                 0.0             255   \n",
       "2           0.05           0.07                 0.0             255   \n",
       "\n",
       "   dst_host_srv_count  dst_host_same_srv_rate  dst_host_diff_srv_rate  \\\n",
       "0                  25                    0.17                    0.03   \n",
       "1                   1                    0.00                    0.60   \n",
       "2                  26                    0.10                    0.05   \n",
       "\n",
       "   dst_host_same_src_port_rate  dst_host_srv_diff_host_rate  \\\n",
       "0                         0.17                          0.0   \n",
       "1                         0.88                          0.0   \n",
       "2                         0.00                          0.0   \n",
       "\n",
       "   dst_host_serror_rate  dst_host_srv_serror_rate  dst_host_rerror_rate  \\\n",
       "0                   0.0                       0.0                  0.05   \n",
       "1                   0.0                       0.0                  0.00   \n",
       "2                   1.0                       1.0                  0.00   \n",
       "\n",
       "   dst_host_srv_rerror_rate attack_class  \n",
       "0                       0.0       Normal  \n",
       "1                       0.0       Normal  \n",
       "2                       0.0          DoS  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# View top 3 train data \n",
    "dfkdd_train.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exploratory Data Analysis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>duration</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>land</th>\n",
       "      <th>wrong_fragment</th>\n",
       "      <th>urgent</th>\n",
       "      <th>hot</th>\n",
       "      <th>num_failed_logins</th>\n",
       "      <th>logged_in</th>\n",
       "      <th>num_compromised</th>\n",
       "      <th>root_shell</th>\n",
       "      <th>su_attempted</th>\n",
       "      <th>num_root</th>\n",
       "      <th>num_file_creations</th>\n",
       "      <th>num_shells</th>\n",
       "      <th>num_access_files</th>\n",
       "      <th>num_outbound_cmds</th>\n",
       "      <th>is_host_login</th>\n",
       "      <th>is_guest_login</th>\n",
       "      <th>count</th>\n",
       "      <th>srv_count</th>\n",
       "      <th>serror_rate</th>\n",
       "      <th>srv_serror_rate</th>\n",
       "      <th>rerror_rate</th>\n",
       "      <th>srv_rerror_rate</th>\n",
       "      <th>same_srv_rate</th>\n",
       "      <th>diff_srv_rate</th>\n",
       "      <th>srv_diff_host_rate</th>\n",
       "      <th>dst_host_count</th>\n",
       "      <th>dst_host_srv_count</th>\n",
       "      <th>dst_host_same_srv_rate</th>\n",
       "      <th>dst_host_diff_srv_rate</th>\n",
       "      <th>dst_host_same_src_port_rate</th>\n",
       "      <th>dst_host_srv_diff_host_rate</th>\n",
       "      <th>dst_host_serror_rate</th>\n",
       "      <th>dst_host_srv_serror_rate</th>\n",
       "      <th>dst_host_rerror_rate</th>\n",
       "      <th>dst_host_srv_rerror_rate</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>125973.00000</td>\n",
       "      <td>1.259730e+05</td>\n",
       "      <td>1.259730e+05</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.0</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "      <td>125973.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>287.14465</td>\n",
       "      <td>4.556674e+04</td>\n",
       "      <td>1.977911e+04</td>\n",
       "      <td>0.000198</td>\n",
       "      <td>0.022687</td>\n",
       "      <td>0.000111</td>\n",
       "      <td>0.204409</td>\n",
       "      <td>0.001222</td>\n",
       "      <td>0.395736</td>\n",
       "      <td>0.279250</td>\n",
       "      <td>0.001342</td>\n",
       "      <td>0.001103</td>\n",
       "      <td>0.302192</td>\n",
       "      <td>0.012669</td>\n",
       "      <td>0.000413</td>\n",
       "      <td>0.004096</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000008</td>\n",
       "      <td>0.009423</td>\n",
       "      <td>84.107555</td>\n",
       "      <td>27.737888</td>\n",
       "      <td>0.284485</td>\n",
       "      <td>0.282485</td>\n",
       "      <td>0.119958</td>\n",
       "      <td>0.121183</td>\n",
       "      <td>0.660928</td>\n",
       "      <td>0.063053</td>\n",
       "      <td>0.097322</td>\n",
       "      <td>182.148945</td>\n",
       "      <td>115.653005</td>\n",
       "      <td>0.521242</td>\n",
       "      <td>0.082951</td>\n",
       "      <td>0.148379</td>\n",
       "      <td>0.032542</td>\n",
       "      <td>0.284452</td>\n",
       "      <td>0.278485</td>\n",
       "      <td>0.118832</td>\n",
       "      <td>0.120240</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>2604.51531</td>\n",
       "      <td>5.870331e+06</td>\n",
       "      <td>4.021269e+06</td>\n",
       "      <td>0.014086</td>\n",
       "      <td>0.253530</td>\n",
       "      <td>0.014366</td>\n",
       "      <td>2.149968</td>\n",
       "      <td>0.045239</td>\n",
       "      <td>0.489010</td>\n",
       "      <td>23.942042</td>\n",
       "      <td>0.036603</td>\n",
       "      <td>0.045154</td>\n",
       "      <td>24.399618</td>\n",
       "      <td>0.483935</td>\n",
       "      <td>0.022181</td>\n",
       "      <td>0.099370</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.002817</td>\n",
       "      <td>0.096612</td>\n",
       "      <td>114.508607</td>\n",
       "      <td>72.635840</td>\n",
       "      <td>0.446456</td>\n",
       "      <td>0.447022</td>\n",
       "      <td>0.320436</td>\n",
       "      <td>0.323647</td>\n",
       "      <td>0.439623</td>\n",
       "      <td>0.180314</td>\n",
       "      <td>0.259830</td>\n",
       "      <td>99.206213</td>\n",
       "      <td>110.702741</td>\n",
       "      <td>0.448949</td>\n",
       "      <td>0.188922</td>\n",
       "      <td>0.308997</td>\n",
       "      <td>0.112564</td>\n",
       "      <td>0.444784</td>\n",
       "      <td>0.445669</td>\n",
       "      <td>0.306557</td>\n",
       "      <td>0.319459</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>0.00000</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.090000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>82.000000</td>\n",
       "      <td>10.000000</td>\n",
       "      <td>0.050000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>0.00000</td>\n",
       "      <td>4.400000e+01</td>\n",
       "      <td>0.000000e+00</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>14.000000</td>\n",
       "      <td>8.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>255.000000</td>\n",
       "      <td>63.000000</td>\n",
       "      <td>0.510000</td>\n",
       "      <td>0.020000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>0.00000</td>\n",
       "      <td>2.760000e+02</td>\n",
       "      <td>5.160000e+02</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>143.000000</td>\n",
       "      <td>18.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.060000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>255.000000</td>\n",
       "      <td>255.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.070000</td>\n",
       "      <td>0.060000</td>\n",
       "      <td>0.020000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>42908.00000</td>\n",
       "      <td>1.379964e+09</td>\n",
       "      <td>1.309937e+09</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>3.000000</td>\n",
       "      <td>77.000000</td>\n",
       "      <td>5.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>7479.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>7468.000000</td>\n",
       "      <td>43.000000</td>\n",
       "      <td>2.000000</td>\n",
       "      <td>9.000000</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>511.000000</td>\n",
       "      <td>511.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>255.000000</td>\n",
       "      <td>255.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           duration     src_bytes     dst_bytes           land  \\\n",
       "count  125973.00000  1.259730e+05  1.259730e+05  125973.000000   \n",
       "mean      287.14465  4.556674e+04  1.977911e+04       0.000198   \n",
       "std      2604.51531  5.870331e+06  4.021269e+06       0.014086   \n",
       "min         0.00000  0.000000e+00  0.000000e+00       0.000000   \n",
       "25%         0.00000  0.000000e+00  0.000000e+00       0.000000   \n",
       "50%         0.00000  4.400000e+01  0.000000e+00       0.000000   \n",
       "75%         0.00000  2.760000e+02  5.160000e+02       0.000000   \n",
       "max     42908.00000  1.379964e+09  1.309937e+09       1.000000   \n",
       "\n",
       "       wrong_fragment         urgent            hot  num_failed_logins  \\\n",
       "count   125973.000000  125973.000000  125973.000000      125973.000000   \n",
       "mean         0.022687       0.000111       0.204409           0.001222   \n",
       "std          0.253530       0.014366       2.149968           0.045239   \n",
       "min          0.000000       0.000000       0.000000           0.000000   \n",
       "25%          0.000000       0.000000       0.000000           0.000000   \n",
       "50%          0.000000       0.000000       0.000000           0.000000   \n",
       "75%          0.000000       0.000000       0.000000           0.000000   \n",
       "max          3.000000       3.000000      77.000000           5.000000   \n",
       "\n",
       "           logged_in  num_compromised     root_shell   su_attempted  \\\n",
       "count  125973.000000    125973.000000  125973.000000  125973.000000   \n",
       "mean        0.395736         0.279250       0.001342       0.001103   \n",
       "std         0.489010        23.942042       0.036603       0.045154   \n",
       "min         0.000000         0.000000       0.000000       0.000000   \n",
       "25%         0.000000         0.000000       0.000000       0.000000   \n",
       "50%         0.000000         0.000000       0.000000       0.000000   \n",
       "75%         1.000000         0.000000       0.000000       0.000000   \n",
       "max         1.000000      7479.000000       1.000000       2.000000   \n",
       "\n",
       "            num_root  num_file_creations     num_shells  num_access_files  \\\n",
       "count  125973.000000       125973.000000  125973.000000     125973.000000   \n",
       "mean        0.302192            0.012669       0.000413          0.004096   \n",
       "std        24.399618            0.483935       0.022181          0.099370   \n",
       "min         0.000000            0.000000       0.000000          0.000000   \n",
       "25%         0.000000            0.000000       0.000000          0.000000   \n",
       "50%         0.000000            0.000000       0.000000          0.000000   \n",
       "75%         0.000000            0.000000       0.000000          0.000000   \n",
       "max      7468.000000           43.000000       2.000000          9.000000   \n",
       "\n",
       "       num_outbound_cmds  is_host_login  is_guest_login          count  \\\n",
       "count           125973.0  125973.000000   125973.000000  125973.000000   \n",
       "mean                 0.0       0.000008        0.009423      84.107555   \n",
       "std                  0.0       0.002817        0.096612     114.508607   \n",
       "min                  0.0       0.000000        0.000000       0.000000   \n",
       "25%                  0.0       0.000000        0.000000       2.000000   \n",
       "50%                  0.0       0.000000        0.000000      14.000000   \n",
       "75%                  0.0       0.000000        0.000000     143.000000   \n",
       "max                  0.0       1.000000        1.000000     511.000000   \n",
       "\n",
       "           srv_count    serror_rate  srv_serror_rate    rerror_rate  \\\n",
       "count  125973.000000  125973.000000    125973.000000  125973.000000   \n",
       "mean       27.737888       0.284485         0.282485       0.119958   \n",
       "std        72.635840       0.446456         0.447022       0.320436   \n",
       "min         0.000000       0.000000         0.000000       0.000000   \n",
       "25%         2.000000       0.000000         0.000000       0.000000   \n",
       "50%         8.000000       0.000000         0.000000       0.000000   \n",
       "75%        18.000000       1.000000         1.000000       0.000000   \n",
       "max       511.000000       1.000000         1.000000       1.000000   \n",
       "\n",
       "       srv_rerror_rate  same_srv_rate  diff_srv_rate  srv_diff_host_rate  \\\n",
       "count    125973.000000  125973.000000  125973.000000       125973.000000   \n",
       "mean          0.121183       0.660928       0.063053            0.097322   \n",
       "std           0.323647       0.439623       0.180314            0.259830   \n",
       "min           0.000000       0.000000       0.000000            0.000000   \n",
       "25%           0.000000       0.090000       0.000000            0.000000   \n",
       "50%           0.000000       1.000000       0.000000            0.000000   \n",
       "75%           0.000000       1.000000       0.060000            0.000000   \n",
       "max           1.000000       1.000000       1.000000            1.000000   \n",
       "\n",
       "       dst_host_count  dst_host_srv_count  dst_host_same_srv_rate  \\\n",
       "count   125973.000000       125973.000000           125973.000000   \n",
       "mean       182.148945          115.653005                0.521242   \n",
       "std         99.206213          110.702741                0.448949   \n",
       "min          0.000000            0.000000                0.000000   \n",
       "25%         82.000000           10.000000                0.050000   \n",
       "50%        255.000000           63.000000                0.510000   \n",
       "75%        255.000000          255.000000                1.000000   \n",
       "max        255.000000          255.000000                1.000000   \n",
       "\n",
       "       dst_host_diff_srv_rate  dst_host_same_src_port_rate  \\\n",
       "count           125973.000000                125973.000000   \n",
       "mean                 0.082951                     0.148379   \n",
       "std                  0.188922                     0.308997   \n",
       "min                  0.000000                     0.000000   \n",
       "25%                  0.000000                     0.000000   \n",
       "50%                  0.020000                     0.000000   \n",
       "75%                  0.070000                     0.060000   \n",
       "max                  1.000000                     1.000000   \n",
       "\n",
       "       dst_host_srv_diff_host_rate  dst_host_serror_rate  \\\n",
       "count                125973.000000         125973.000000   \n",
       "mean                      0.032542              0.284452   \n",
       "std                       0.112564              0.444784   \n",
       "min                       0.000000              0.000000   \n",
       "25%                       0.000000              0.000000   \n",
       "50%                       0.000000              0.000000   \n",
       "75%                       0.020000              1.000000   \n",
       "max                       1.000000              1.000000   \n",
       "\n",
       "       dst_host_srv_serror_rate  dst_host_rerror_rate  \\\n",
       "count             125973.000000         125973.000000   \n",
       "mean                   0.278485              0.118832   \n",
       "std                    0.445669              0.306557   \n",
       "min                    0.000000              0.000000   \n",
       "25%                    0.000000              0.000000   \n",
       "50%                    0.000000              0.000000   \n",
       "75%                    1.000000              0.000000   \n",
       "max                    1.000000              1.000000   \n",
       "\n",
       "       dst_host_srv_rerror_rate  \n",
       "count             125973.000000  \n",
       "mean                   0.120240  \n",
       "std                    0.319459  \n",
       "min                    0.000000  \n",
       "25%                    0.000000  \n",
       "50%                    0.000000  \n",
       "75%                    0.000000  \n",
       "max                    1.000000  "
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Descriptive statistics\n",
    "dfkdd_train.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0    125973\n",
       "Name: num_outbound_cmds, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "0    22544\n",
       "Name: num_outbound_cmds, dtype: int64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfkdd_train['num_outbound_cmds'].value_counts()\n",
    "dfkdd_test['num_outbound_cmds'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# 'num_outbound_cmds' field has all 0 values. Hence, it will be removed from both train and test dataset since it is a redundant field.\n",
    "dfkdd_train.drop(['num_outbound_cmds'], axis=1, inplace=True)\n",
    "dfkdd_test.drop(['num_outbound_cmds'], axis=1, inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>attack_class</th>\n",
       "      <th>frequency_percent_train</th>\n",
       "      <th>attack_class</th>\n",
       "      <th>frequency_percent_test</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>DoS</th>\n",
       "      <td>45927</td>\n",
       "      <td>36.46</td>\n",
       "      <td>7458</td>\n",
       "      <td>33.08</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Normal</th>\n",
       "      <td>67343</td>\n",
       "      <td>53.46</td>\n",
       "      <td>9711</td>\n",
       "      <td>43.08</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Probe</th>\n",
       "      <td>11656</td>\n",
       "      <td>9.25</td>\n",
       "      <td>2421</td>\n",
       "      <td>10.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>R2L</th>\n",
       "      <td>995</td>\n",
       "      <td>0.79</td>\n",
       "      <td>2754</td>\n",
       "      <td>12.22</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>U2R</th>\n",
       "      <td>52</td>\n",
       "      <td>0.04</td>\n",
       "      <td>200</td>\n",
       "      <td>0.89</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "        attack_class  frequency_percent_train  attack_class  \\\n",
       "DoS            45927                    36.46          7458   \n",
       "Normal         67343                    53.46          9711   \n",
       "Probe          11656                     9.25          2421   \n",
       "R2L              995                     0.79          2754   \n",
       "U2R               52                     0.04           200   \n",
       "\n",
       "        frequency_percent_test  \n",
       "DoS                      33.08  \n",
       "Normal                   43.08  \n",
       "Probe                    10.74  \n",
       "R2L                      12.22  \n",
       "U2R                       0.89  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Attack Class Distribution\n",
    "attack_class_freq_train = dfkdd_train[['attack_class']].apply(lambda x: x.value_counts())\n",
    "attack_class_freq_test = dfkdd_test[['attack_class']].apply(lambda x: x.value_counts())\n",
    "attack_class_freq_train['frequency_percent_train'] = round((100 * attack_class_freq_train / attack_class_freq_train.sum()),2)\n",
    "attack_class_freq_test['frequency_percent_test'] = round((100 * attack_class_freq_test / attack_class_freq_test.sum()),2)\n",
    "\n",
    "attack_class_dist = pd.concat([attack_class_freq_train,attack_class_freq_test], axis=1) \n",
    "attack_class_dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeEAAAF7CAYAAADltzMrAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmczXX///HnLLYJIy6MLUnORMggYSzFjHUMM5LlsiW6\nRhTf1GUtsi8Xsg0SJQYVY78QJUUXUUK2rss2FNMkjDFm//z+8JuTadbGHG+Ox/1269ac93mfz+d1\n3nPM87w/q4tlWZYAAMBd52q6AAAAHlSEMAAAhhDCAAAYQggDAGAIIQwAgCGEMAAAhhDCyFN9+/aV\nt7e3+vXrl2mf69eva/ny5enad+/ercOHDzuyPF24cEHe3t565ZVX7nhZZ8+e1ZQpUxQQECAfHx/V\nqlVLQUFBWrhwoWJjYx22Xkfq0aOHvL290/xXrVo11alTR+3bt9esWbMUHR2d7nXh4eHy9vbWhx9+\nmKv1btq0SefPn/9LNabWcafrzkpycrKWL1+e5vc5Z84ceXt7a8eOHXm+Pjx43E0XAOcRFRWlb775\nRoUKFdLu3bt16dIleXl5pevXsmVLlSxZUt27d7e3rVixQu+8847mzZt3N0vOtbCwME2aNEnJycny\n9fWVr6+v4uPjtW/fPs2YMUMbNmzQsmXLVLx4cdOl5krPnj1VtGhRSVJSUpKuXr2qAwcOKDQ0VGvX\nrtXy5ctVvnx5e/+qVatq4MCBqlWr1l9e17Rp0/T+++9r3bp1OeofFBSkevXqqUCBAn95XX/VkCFD\ntGXLFgUGBtrb6tWrp4EDB6pSpUoOXz+cHyGMPLNx40YlJyerb9++mjNnjlavXq2BAwem63f58mWV\nLFkyXdv9Yv369Ro7dqwqVqyo+fPnq3LlyvbnkpOTNXPmTC1atEghISH65JNPDFaae7169UoTspKU\nkpKiOXPmKDQ0VCEhIVq3bp3c3W/9CalataqqVq2aq3X91d99cHBwrtaTGxnV9swzz+iZZ565azXA\nubE5Gnlm3bp18vT0VN++fVWkSBGFh4fL2S7IFh0drXHjxilfvnxavHhxmgCWJDc3N73xxhvy8fHR\noUOH9NVXXxmqNO+5urpq0KBBatKkif773/9q/fr1pksC7nuEMPLEiRMndPLkSTVo0EAFCxaUn5+f\nfv75Z+3Zs8feZ9++ffL29rb39/b21pw5c9SjRw/NnTtXkjRgwAB7H0m6ceOG5s2bp/bt28vHx0c1\natRQixYtNHXq1HT7XSVpx44d6tGjh+rWratnnnlGvXv31v79+7Os3bIsDR8+XN7e3ho6dKhSUlIy\n7btt2zZdv35d7dq1U4UKFTLt98Ybb2jMmDF6/PHHs1z3zz//rNGjR8vPz081atSQj4+PgoODtXLl\nynR9N23apC5duujpp5+Wj4+POnbsqBUrVqT7opPTfrnVp08fSdK///1ve1tG+2V/++03jRgxQv7+\n/qpRo4YaNWqkN998U+fOnbP3adasmdauXStJ6tChg5o1aybpj/2u//nPf9SpUydVr15dLVu21I0b\nN9LtE05lWZZCQ0PVtGlT1axZU88//7y2bt2apk/qZ3DChAnp3tewYcPk7e2t48ePS5K8vb317bff\nSpKefvpp9ejRI01tf94nvGfPHr344ouqXbu2atasqaCgIIWFhaX7PDVr1kw9evTQqVOnFBISojp1\n6sjHx0f9+vXTiRMnshl9OBtCGHkidX9emzZt0vz/008/tfcpV66cffP03/72Nw0cOFD16tWz7+NL\nfV1qn6SkJL344ouaM2eOSpYsqW7duqljx46Ki4vT4sWLNWzYsDQ1LFy4UAMGDNCpU6fUsmVLtW3b\nVseOHVPv3r3TfBn4sylTpig8PFwBAQGaNGmSXF0z/2eROrNt3LhxluNRt25dde3aVWXLls20z4UL\nF9SxY0etW7dOtWrVUu/eveXv769Tp05pzJgxaQ5e27x5s4YMGaIrV64oKChInTt3VnR0tN555x2F\nhob+5X53onbt2nJ1ddX333+faZ/4+Hj169dP69ev15NPPqnevXurTp062rx5s7p06aKrV69KurXv\n+YknnpAkde7cWT179kyznDfeeEMFCxZUjx499Mwzz+ihhx7KdJ2LFy/WwoUL1bhxY3Xo0EHnz5/X\noEGDMvxCkxMDBw5UuXLlJEn9+vVTUFBQpn2XLVumPn366MiRI/L391fHjh11/fp1jR07VkOGDEn3\nBejixYvq0qWLLl++rBdeeEHPPPOMvvrqK/Xo0UO///57rurFfcoC7lBSUpLl6+tr+fj4WHFxcZZl\nWVZiYqLVoEED68knn7QuX76cpr/NZrMCAwPTtM2ePduy2WzW9u3b7W2bNm2ybDabNWPGjDR9r1+/\nbjVs2NCqWrWqFRsba1mWZZ0+fdqqVq2a1apVK+vXX3+19z179qxVq1YtKyAgwLIsyzp//rxls9ms\n/v37W5ZlWfPmzbNsNpv16quvWomJidm+1+eff96y2WzW0aNHczo8Ga7Xsizrrbfesmw2m7Vnz540\nfQ8dOmTZbDarc+fO9ragoCCrVq1a1vXr19OMg6+vr1W/fn0rJSXlL/XLTPfu3S2bzWadP38+y371\n69e3bDabfT1r1qyxbDab9cEHH1iWZVlffPGFZbPZrFmzZqV53fvvv2/ZbDZr+fLl9rahQ4daNpvN\nOnbsmL0t9fMQHBxsJScnZ1jjtWvX0qy7WrVq1pEjR+z9zp8/b/n6+lq1atWy9927d69ls9ms8ePH\np3tPGdXx53XdXlvqZzUiIsKqVq2a9eyzz1oRERH2fjdu3LB69uxp2Ww2a+3atfb25557zrLZbNY7\n77yT5vcxatQoy2azWStWrMhwzOGcmAnjju3Zs0dRUVHy9/e3H7Hq7u6uVq1aKTExMdf7DqtVq6bx\n48erV69eadoLFy6satWqKTk5WdeuXZMkbd26VUlJSXrllVfSHPRVsWJFDR06VB07dlRiYmKa5YSF\nhWnWrFl67rnnNH36dPtBRllJ3QSa1YwspwIDAzVx4kQ1bNgwTXvNmjVVsGDBNAcFWZaluLg4/fe/\n/7W3FS5cWKtXr9bnn38uFxeXv9TvTuXPn1/Srd0FGUndBHvy5EnFx8fb27t166Yvv/xS3bp1y9F6\n/P39s9wycbvAwEBVr17d/rh8+fLq2bOnYmNjHXo60YYNG5SUlKQBAwak2UXh4eGhUaNGSZLWrFmT\n7nX9+vVL8/to2rSppFu7KPDg4Oho3LHUkG3btm2a9nbt2iksLEyrV6/Wiy+++JeXW6lSJVWqVEnx\n8fE6dOiQzpw5o4iICB09etS+ry45OVmS7PvSMjpFpkuXLunaDh8+rJ07d0qSGjVqpHz58uWopocf\nflhnz561h/+dqFu3rurWraurV6/q+PHjioiI0JkzZ/TDDz8oPj7e/t6kW5tqR48erS5dusjb21tN\nmjRR06ZNVadOnTQhldN+dyo1fD08PDJ8vmHDhqpQoYJ27Nihhg0bqmHDhmrSpImeffZZlSlTJsfr\n+fMR2lmpXbt2urYaNWpIkkP3taYu++mnn073XJUqVVS0aNF06y9QoEC6cShcuLAkKSEhwUGV4l5E\nCOOOxMTE2GcZmV2g43//+5++//77DP9IZiUlJUULFy7UBx98YA+9EiVKyMfHR+XKldOpU6fs+9pS\n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\nudyNG9fJ07OY5s1bpMmTp2vGjKmSpBs3bsjPr6Xmzn1PJUuW0t69e/TVV1/q2rWrWrToI82evUAn\nThxXQEB7bd26WZK0fftWtWjRKsv1lStXXrNnL1CfPi8rNHSWzpw5neF7kKQ6depqwYIlOnjwu3Tr\n/c9/9ujixZ81f/5izZ69QKtWrdD167duBFS16pOaNStUdes+o+3btykgoIOKFy+hMWMmZliTm5ub\nunfvLX//VmrUqKkkyc+vpWbNCtXPP1+Qn18LzZw5TzNnztPHH4ele32+fPk1ffpsDRo0RB9/vCLL\n959TzIQB4B71yCMVJUmnT59SZOQlDRrUX5J0/fp1nT9/Xhcv/qKqVatLkmrXrqvz5yPSLcOybv3/\n1Kn/6fDhgzp27EdJUnJykq5evSpJstm8JUmlSpVWQkKCLl68qCefrClJKlq0qPr1u7VeD4+HdObM\naW3fvlWTJ8/IsvbatZ+WJFWv/pRmz56R6Xu4/X1GRJxLt96wsKU6efKEBg58WdKtfeaXLv2Spu7S\npUvr8uXLORnSdFLXXbx4cX3yyQrt2rVTHh4PZbhf+Y9x8lJCQnyu1vdnhDByLK+PFE01e2BthywX\nuN+5urpIuhUUjz76mKZPny0XFxd9/HGYKleuosqVq+jw4R/UsGEjnThxzP66pKQkxcbGKl++fDpz\n5pQkqWLFR1WqVCn17NlH8fFxWrr09n3OLmnW++ijj2rnzs8lSTExMXr77WGaMWOuAgM76MMP31fJ\nkqVUrFixLGs/efK4nnqqlo4cOaRKlSpn+h6+/PJzubi4Zrre4OBO8vGpq6FDRyolJUXvvTfXPut3\ncXFJt14XF1dZqd88MuDi4iLLSrltjG+te9Wq5apevaaCgp7X998f0H/+szuD12b5lnOFEAaATPzV\nU4piYq6qcOGswyk3qlSxqW7dp/XKKy8pISFRVas+qZIlS+qVV17TpEnj9PHHYcqXL58efri4JOmF\nF7rqH//orbJly8nLq4wkqX37YE2ZMl4DB76sGzdiFBTUyR5Af9aoUVMdOPCt+vd/ScnJyXrxxX6S\npCZNntPMmVP11lvjsq15795vtHv3LqWkpGjEiNEqW7Zchu8hu/XWr99QBw9+p1de6aubN2NVv34D\neXg8lOl6n3qqlt544zXNmbMww5CuXPlxffTREtlsT6Rp9/Vtopkzp+rzzz9T4cKF5ebmpoSEhGzf\n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\nbm5at24dR/rnkSZNmqhfv3765z//qapVq+qRRx7RjBkz9Oqrr5ouzWmcPXtWs2fPliQ1bNhQ3bt3\n14cffuhUF04ihDPwxBNPaOLEierevbskKSwsTDabzXBVziUyMlL//ve/mTE4yLJly9I8vv2c1tRr\no+POvPnmm1q9erUSEhLsbfXr19fChQs1d+5cg5U5jwdhawP7hDMQExOj8ePH6+uvv1ZKSooaNWqk\nkSNHqlixYqZLcxqDBg3SqFGjVLJkSdOlPBCSkpLSbeGB4+zZs0e+vr6my7jvTZ06VcePH7dvbZCk\nvXv32rc27N+/32R5eYKZ8J9s375d77//vn766ScVLFhQNptNAQEBBHAea9WqlVq3bi2bzZbmqPOP\nPvrIYFXO5/Llyxo6dKj27t2r5ORkPf3005o2bZpKly5turT7Xupd1ooVK6aJEyeqePHi+uWXXzRh\nwgR9/fXXOnz4sOkS73sPwtYGZsK3WbdunUJDQ/Xaa6/piSeekIuLi44cOaL58+dryJAhatGihekS\nnUazZs3UtWtXPfLII2naucFD3ho0aJCqVKminj17Kjk5WcuWLdPx48c5FSwPdOrUSa1bt7ZfFtTH\nx0cjR45U7dq1NWrUKFWqVMl0ibgPEMK36dixo+bMmaOyZcumaT9z5oxGjBihlStXGqrM+bRr104b\nN240XYbTa9++vdavX5+mrW3btpyilAdatWqlrVu3Kjk5WS1btlRcXJyGDx/OJSvzUI8ePdLs+3Vz\nc1OxYsXUtGlTdejQwWBleYfN0bdJTExMF8DSrSNM4+PjDVTkvJ577jmFhYXJ399f+fPnt7ez2T9v\nJSUlKT4+3n5a0s2bN53mgBbTChUqJOlWMMTHx2vRokX2/ZbIG6kHx6ZKSUnR5cuXtWzZMl25ckUv\nvviiocryDiF8m6wuTckGg7z14YcfKiEhQePGjbO3ubi46Pjx4warcj5t2rRR7969FRwcLEkKDw9n\nk38euf1vQvHixQlgB8jss9quXTv16NGDEAZya8WKFZyvehcMGDBAXl5e9iP9g4OD9fzzz5suyymk\npKTo2rVrsixLlmXZf07FVh3H8fT0dJotOuwTvk21atVUsGDBdO2WZSkhIUFHjx41UJVzat26tbZs\n2WK6DKfXq1cvLV261HQZTin14M2M/oSyVcexLMtSQECAUxzbwEz4Ntu3bzddwgPD29tbGzduVJ06\ndeTh4WFvZ/aQt65fv26/Rjfy1okTJ0yX4PRuv6zt7W3Lli1TrVq1DFSU95gJw4gaNWooMTExTRuz\nh7z397//Xf/73//k7e2dJogXLFhgsCogZ/68tcHFxUXFixdXkyZNNGLECBUpUsRwhXeOEAac1E8/\n/aTdu3crPj5eXl5eaZ4LCgoyVBWA27E5GkZwz2bHWrNmjaZMmaKKFSsqIiJC//rXv9S4cWPTZQH4\nE2bCMCKjezY/9thjGjlypOnSnEKHDh20cOFClS5dWgcPHtTMmTO5JChwD2LaASMyu2cz8k7q9aF9\nfHx05coVw9UAyIir6QLwYOKezY7153Mos7oQDQBzCGEYkXrP5oiICEVERGjixIncs9mBnOXCBoCz\nYZ8wjMjons2jRo2Sp6en6dKcwp8vPBMXF6eCBQvKsiy5uLjo+++/N1gdgFSEMO6q4cOHZ/qci4uL\nJk6ceBercV4///xzls+XK1fuLlUCICscmIW7qkqVKunarly5oqVLlxIMeYixBO4PzIRh1DfffKOh\nQ4eqSZMmGjVqlP32cADwIGAmDCOSkpI0ffp0rV27VmPGjFGrVq1MlwQAdx0hjLvu3Llz+r//+z95\neHho7dq1KlOmjOmSAMAITlHCXbV69Wp16tRJ/v7+Wr58OQEM4IHGPmHcVU888YRcXV1VoECBNOeu\ncuoMgAcRIYy7ilNnAOAPhDAAAIawTxgAAEMIYQAADCGEAQAwhBAGAMCQ/wcDhzw7RWzJYQAAAABJ\nRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10a891dd8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Attack class bar plot\n",
    "plot = attack_class_dist[['frequency_percent_train', 'frequency_percent_test']].plot(kind=\"bar\");\n",
    "plot.set_title(\"Attack Class Distribution\", fontsize=20);\n",
    "plot.grid(color='lightgray', alpha=0.5);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>duration</th>\n",
       "      <th>protocol_type</th>\n",
       "      <th>service</th>\n",
       "      <th>flag</th>\n",
       "      <th>src_bytes</th>\n",
       "      <th>dst_bytes</th>\n",
       "      <th>land</th>\n",
       "      <th>wrong_fragment</th>\n",
       "      <th>urgent</th>\n",
       "      <th>hot</th>\n",
       "      <th>num_failed_logins</th>\n",
       "      <th>logged_in</th>\n",
       "      <th>num_compromised</th>\n",
       "      <th>root_shell</th>\n",
       "      <th>su_attempted</th>\n",
       "      <th>num_root</th>\n",
       "      <th>num_file_creations</th>\n",
       "      <th>num_shells</th>\n",
       "      <th>num_access_files</th>\n",
       "      <th>is_host_login</th>\n",
       "      <th>is_guest_login</th>\n",
       "      <th>count</th>\n",
       "      <th>srv_count</th>\n",
       "      <th>serror_rate</th>\n",
       "      <th>srv_serror_rate</th>\n",
       "      <th>rerror_rate</th>\n",
       "      <th>srv_rerror_rate</th>\n",
       "      <th>same_srv_rate</th>\n",
       "      <th>diff_srv_rate</th>\n",
       "      <th>srv_diff_host_rate</th>\n",
       "      <th>dst_host_count</th>\n",
       "      <th>dst_host_srv_count</th>\n",
       "      <th>dst_host_same_srv_rate</th>\n",
       "      <th>dst_host_diff_srv_rate</th>\n",
       "      <th>dst_host_same_src_port_rate</th>\n",
       "      <th>dst_host_srv_diff_host_rate</th>\n",
       "      <th>dst_host_serror_rate</th>\n",
       "      <th>dst_host_srv_serror_rate</th>\n",
       "      <th>dst_host_rerror_rate</th>\n",
       "      <th>dst_host_srv_rerror_rate</th>\n",
       "      <th>attack_class</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>ftp_data</td>\n",
       "      <td>SF</td>\n",
       "      <td>491</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>150</td>\n",
       "      <td>25</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.17</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>udp</td>\n",
       "      <td>other</td>\n",
       "      <td>SF</td>\n",
       "      <td>146</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>13</td>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.08</td>\n",
       "      <td>0.15</td>\n",
       "      <td>0.00</td>\n",
       "      <td>255</td>\n",
       "      <td>1</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.60</td>\n",
       "      <td>0.88</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>private</td>\n",
       "      <td>S0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>123</td>\n",
       "      <td>6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.07</td>\n",
       "      <td>0.00</td>\n",
       "      <td>255</td>\n",
       "      <td>26</td>\n",
       "      <td>0.10</td>\n",
       "      <td>0.05</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>DoS</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "      <td>232</td>\n",
       "      <td>8153</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0.2</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>30</td>\n",
       "      <td>255</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.04</td>\n",
       "      <td>0.03</td>\n",
       "      <td>0.01</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.01</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>tcp</td>\n",
       "      <td>http</td>\n",
       "      <td>SF</td>\n",
       "      <td>199</td>\n",
       "      <td>420</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>30</td>\n",
       "      <td>32</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.09</td>\n",
       "      <td>255</td>\n",
       "      <td>255</td>\n",
       "      <td>1.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>0.00</td>\n",
       "      <td>Normal</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   duration protocol_type   service flag  src_bytes  dst_bytes  land  \\\n",
       "0         0           tcp  ftp_data   SF        491          0     0   \n",
       "1         0           udp     other   SF        146          0     0   \n",
       "2         0           tcp   private   S0          0          0     0   \n",
       "3         0           tcp      http   SF        232       8153     0   \n",
       "4         0           tcp      http   SF        199        420     0   \n",
       "\n",
       "   wrong_fragment  urgent  hot  num_failed_logins  logged_in  num_compromised  \\\n",
       "0               0       0    0                  0          0                0   \n",
       "1               0       0    0                  0          0                0   \n",
       "2               0       0    0                  0          0                0   \n",
       "3               0       0    0                  0          1                0   \n",
       "4               0       0    0                  0          1                0   \n",
       "\n",
       "   root_shell  su_attempted  num_root  num_file_creations  num_shells  \\\n",
       "0           0             0         0                   0           0   \n",
       "1           0             0         0                   0           0   \n",
       "2           0             0         0                   0           0   \n",
       "3           0             0         0                   0           0   \n",
       "4           0             0         0                   0           0   \n",
       "\n",
       "   num_access_files  is_host_login  is_guest_login  count  srv_count  \\\n",
       "0                 0              0               0      2          2   \n",
       "1                 0              0               0     13          1   \n",
       "2                 0              0               0    123          6   \n",
       "3                 0              0               0      5          5   \n",
       "4                 0              0               0     30         32   \n",
       "\n",
       "   serror_rate  srv_serror_rate  rerror_rate  srv_rerror_rate  same_srv_rate  \\\n",
       "0          0.0              0.0          0.0              0.0           1.00   \n",
       "1          0.0              0.0          0.0              0.0           0.08   \n",
       "2          1.0              1.0          0.0              0.0           0.05   \n",
       "3          0.2              0.2          0.0              0.0           1.00   \n",
       "4          0.0              0.0          0.0              0.0           1.00   \n",
       "\n",
       "   diff_srv_rate  srv_diff_host_rate  dst_host_count  dst_host_srv_count  \\\n",
       "0           0.00                0.00             150                  25   \n",
       "1           0.15                0.00             255                   1   \n",
       "2           0.07                0.00             255                  26   \n",
       "3           0.00                0.00              30                 255   \n",
       "4           0.00                0.09             255                 255   \n",
       "\n",
       "   dst_host_same_srv_rate  dst_host_diff_srv_rate  \\\n",
       "0                    0.17                    0.03   \n",
       "1                    0.00                    0.60   \n",
       "2                    0.10                    0.05   \n",
       "3                    1.00                    0.00   \n",
       "4                    1.00                    0.00   \n",
       "\n",
       "   dst_host_same_src_port_rate  dst_host_srv_diff_host_rate  \\\n",
       "0                         0.17                         0.00   \n",
       "1                         0.88                         0.00   \n",
       "2                         0.00                         0.00   \n",
       "3                         0.03                         0.04   \n",
       "4                         0.00                         0.00   \n",
       "\n",
       "   dst_host_serror_rate  dst_host_srv_serror_rate  dst_host_rerror_rate  \\\n",
       "0                  0.00                      0.00                  0.05   \n",
       "1                  0.00                      0.00                  0.00   \n",
       "2                  1.00                      1.00                  0.00   \n",
       "3                  0.03                      0.01                  0.00   \n",
       "4                  0.00                      0.00                  0.00   \n",
       "\n",
       "   dst_host_srv_rerror_rate attack_class  \n",
       "0                      0.00       Normal  \n",
       "1                      0.00       Normal  \n",
       "2                      0.00          DoS  \n",
       "3                      0.01       Normal  \n",
       "4                      0.00       Normal  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dfkdd_train.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scaling Numerical Attributes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "scaler = StandardScaler()\n",
    "\n",
    "# extract numerical attributes and scale it to have zero mean and unit variance  \n",
    "cols = dfkdd_train.select_dtypes(include=['float64','int64']).columns\n",
    "sc_train = scaler.fit_transform(dfkdd_train.select_dtypes(include=['float64','int64']))\n",
    "sc_test = scaler.fit_transform(dfkdd_test.select_dtypes(include=['float64','int64']))\n",
    "\n",
    "# turn the result back to a dataframe\n",
    "sc_traindf = pd.DataFrame(sc_train, columns = cols)\n",
    "sc_testdf = pd.DataFrame(sc_test, columns = cols)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Encoding of Categorical Attributes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "encoder = LabelEncoder()\n",
    "\n",
    "# extract categorical attributes from both training and test sets \n",
    "cattrain = dfkdd_train.select_dtypes(include=['object']).copy()\n",
    "cattest = dfkdd_test.select_dtypes(include=['object']).copy()\n",
    "\n",
    "# encode the categorical attributes\n",
    "traincat = cattrain.apply(encoder.fit_transform)\n",
    "testcat = cattest.apply(encoder.fit_transform)\n",
    "\n",
    "# separate target column from encoded data \n",
    "enctrain = traincat.drop(['attack_class'], axis=1)\n",
    "enctest = testcat.drop(['attack_class'], axis=1)\n",
    "\n",
    "cat_Ytrain = traincat[['attack_class']].copy()\n",
    "cat_Ytest = testcat[['attack_class']].copy()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Data Sampling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Original dataset shape Counter({1: 67343, 0: 45927, 2: 11656, 3: 995, 4: 52})\n",
      "Resampled dataset shape Counter({0: 67343, 1: 67343, 2: 67343, 3: 67343, 4: 67343})\n"
     ]
    }
   ],
   "source": [
    "from imblearn.over_sampling import RandomOverSampler \n",
    "from collections import Counter\n",
    "\n",
    "# define columns and extract encoded train set for sampling \n",
    "sc_traindf = dfkdd_train.select_dtypes(include=['float64','int64'])\n",
    "refclasscol = pd.concat([sc_traindf, enctrain], axis=1).columns\n",
    "refclass = np.concatenate((sc_train, enctrain.values), axis=1)\n",
    "X = refclass\n",
    "\n",
    "# reshape target column to 1D array shape  \n",
    "c, r = cat_Ytest.values.shape\n",
    "y_test = cat_Ytest.values.reshape(c,)\n",
    "\n",
    "c, r = cat_Ytrain.values.shape\n",
    "y = cat_Ytrain.values.reshape(c,)\n",
    "\n",
    "# apply the random over-sampling\n",
    "ros = RandomOverSampler(random_state=42)\n",
    "X_res, y_res = ros.fit_sample(X, y)\n",
    "print('Original dataset shape {}'.format(Counter(y)))\n",
    "print('Resampled dataset shape {}'.format(Counter(y_res)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Feature Selection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x10adeb278>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from sklearn.ensemble import RandomForestClassifier\n",
    "rfc = RandomForestClassifier();\n",
    "\n",
    "# fit random forest classifier on the training set\n",
    "rfc.fit(X_res, y_res);\n",
    "# extract important features\n",
    "score = np.round(rfc.feature_importances_,3)\n",
    "importances = pd.DataFrame({'feature':refclasscol,'importance':score})\n",
    "importances = importances.sort_values('importance',ascending=False).set_index('feature')\n",
    "# plot importances\n",
    "plt.rcParams['figure.figsize'] = (11, 4)\n",
    "importances.plot.bar();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.feature_selection import RFE\n",
    "import itertools\n",
    "rfc = RandomForestClassifier()\n",
    "\n",
    "# create the RFE model and select 10 attributes\n",
    "rfe = RFE(rfc, n_features_to_select=10)\n",
    "rfe = rfe.fit(X_res, y_res)\n",
    "\n",
    "# summarize the selection of the attributes\n",
    "feature_map = [(i, v) for i, v in itertools.zip_longest(rfe.get_support(), refclasscol)]\n",
    "selected_features = [v for i, v in feature_map if i==True]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['src_bytes',\n",
       " 'dst_bytes',\n",
       " 'logged_in',\n",
       " 'count',\n",
       " 'srv_count',\n",
       " 'dst_host_srv_count',\n",
       " 'dst_host_diff_srv_rate',\n",
       " 'dst_host_same_src_port_rate',\n",
       " 'dst_host_serror_rate',\n",
       " 'service']"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "selected_features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Dataset  Partition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(336715, 41)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "(22544, 41)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# define columns to new dataframe\n",
    "newcol = list(refclasscol)\n",
    "newcol.append('attack_class')\n",
    "\n",
    "# add a dimension to target\n",
    "new_y_res = y_res[:, np.newaxis]\n",
    "\n",
    "# create a dataframe from sampled data\n",
    "res_arr = np.concatenate((X_res, new_y_res), axis=1)\n",
    "res_df = pd.DataFrame(res_arr, columns = newcol) \n",
    "\n",
    "# create test dataframe\n",
    "reftest = pd.concat([sc_testdf, testcat], axis=1)\n",
    "reftest['attack_class'] = reftest['attack_class'].astype(np.float64)\n",
    "reftest['protocol_type'] = reftest['protocol_type'].astype(np.float64)\n",
    "reftest['flag'] = reftest['flag'].astype(np.float64)\n",
    "reftest['service'] = reftest['service'].astype(np.float64)\n",
    "\n",
    "res_df.shape\n",
    "reftest.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "code_folding": [],
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from collections import defaultdict\n",
    "classdict = defaultdict(list)\n",
    "\n",
    "# create two-target classes (normal class and an attack class)  \n",
    "attacklist = [('DoS', 0.0), ('Probe', 2.0), ('R2L', 3.0), ('U2R', 4.0)]\n",
    "normalclass = [('Normal', 1.0)]\n",
    "\n",
    "def create_classdict():\n",
    "    '''This function subdivides train and test dataset into two-class attack labels''' \n",
    "    for j, k in normalclass: \n",
    "        for i, v in attacklist: \n",
    "            restrain_set = res_df.loc[(res_df['attack_class'] == k) | (res_df['attack_class'] == v)]\n",
    "            classdict[j +'_' + i].append(restrain_set)\n",
    "            # test labels\n",
    "            reftest_set = reftest.loc[(reftest['attack_class'] == k) | (reftest['attack_class'] == v)]\n",
    "            classdict[j +'_' + i].append(reftest_set)\n",
    "        \n",
    "create_classdict()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Normal_DoS'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Normal_R2L'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Normal_Probe'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": [
       "'Normal_U2R'"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for k, v in classdict.items():\n",
    "    k"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "pretrain = classdict['Normal_DoS'][0]\n",
    "pretest = classdict['Normal_DoS'][1]\n",
    "grpclass = 'Normal_DoS'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Finalize data preprocessing for training"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,\n",
       "       handle_unknown='error', n_values='auto', sparse=True)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.preprocessing import OneHotEncoder\n",
    "enc = OneHotEncoder()\n",
    "\n",
    "Xresdf = pretrain \n",
    "newtest = pretest\n",
    "\n",
    "Xresdfnew = Xresdf[selected_features]\n",
    "Xresdfnum = Xresdfnew.drop(['service'], axis=1)\n",
    "Xresdfcat = Xresdfnew[['service']].copy()\n",
    "\n",
    "Xtest_features = newtest[selected_features]\n",
    "Xtestdfnum = Xtest_features.drop(['service'], axis=1)\n",
    "Xtestcat = Xtest_features[['service']].copy()\n",
    "\n",
    "\n",
    "# Fit train data\n",
    "enc.fit(Xresdfcat)\n",
    "\n",
    "# Transform train data\n",
    "X_train_1hotenc = enc.transform(Xresdfcat).toarray()\n",
    "       \n",
    "# Transform test data\n",
    "X_test_1hotenc = enc.transform(Xtestcat).toarray()\n",
    "\n",
    "X_train = np.concatenate((Xresdfnum.values, X_train_1hotenc), axis=1)\n",
    "X_test = np.concatenate((Xtestdfnum.values, X_test_1hotenc), axis=1) \n",
    "\n",
    "y_train = Xresdf[['attack_class']].copy()\n",
    "c, r = y_train.values.shape\n",
    "Y_train = y_train.values.reshape(c,)\n",
    "\n",
    "y_test = newtest[['attack_class']].copy()\n",
    "c, r = y_test.values.shape\n",
    "Y_test = y_test.values.reshape(c,)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train Models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from sklearn.svm import SVC \n",
    "from sklearn.naive_bayes import BernoulliNB \n",
    "from sklearn import tree\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.ensemble import VotingClassifier\n",
    "\n",
    "# Train KNeighborsClassifier Model\n",
    "KNN_Classifier = KNeighborsClassifier(n_jobs=-1)\n",
    "KNN_Classifier.fit(X_train, Y_train); \n",
    "\n",
    "# Train LogisticRegression Model\n",
    "LGR_Classifier = LogisticRegression(n_jobs=-1, random_state=0)\n",
    "LGR_Classifier.fit(X_train, Y_train);\n",
    "\n",
    "# Train Gaussian Naive Baye Model\n",
    "BNB_Classifier = BernoulliNB()\n",
    "BNB_Classifier.fit(X_train, Y_train)\n",
    "            \n",
    "# Train Decision Tree Model\n",
    "DTC_Classifier = tree.DecisionTreeClassifier(criterion='entropy', random_state=0)\n",
    "DTC_Classifier.fit(X_train, Y_train);\n",
    "            \n",
    "# Train RandomForestClassifier Model\n",
    "#RF_Classifier = RandomForestClassifier(criterion='entropy', n_jobs=-1, random_state=0)\n",
    "#RF_Classifier.fit(X_train, Y_train);  \n",
    "\n",
    "# Train SVM Model\n",
    "#SVC_Classifier = SVC(random_state=0)\n",
    "#SVC_Classifier.fit(X_train, Y_train)\n",
    "\n",
    "## Train Ensemble Model (This method combines all the individual models above except RandomForest)\n",
    "#combined_model = [('Naive Baye Classifier', BNB_Classifier), \n",
    "#                  ('Decision Tree Classifier', DTC_Classifier), \n",
    "#                  ('KNeighborsClassifier', KNN_Classifier), \n",
    "#                  ('LogisticRegression', LGR_Classifier)\n",
    "#                 ]\n",
    "#VotingClassifier =  VotingClassifier(estimators = combined_model,voting = 'soft', n_jobs=-1)\n",
    "#VotingClassifier.fit(X_train, Y_train);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Evaluate Models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "============================== Normal_DoS Naive Baye Classifier Model Evaluation ==============================\n",
      "\n",
      "Cross Validation Mean Score:\n",
      " 0.973776072139\n",
      "\n",
      "Model Accuracy:\n",
      " 0.973768617377\n",
      "\n",
      "Confusion matrix:\n",
      " [[65346  1997]\n",
      " [ 1536 65807]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.98      0.97      0.97     67343\n",
      "        1.0       0.97      0.98      0.97     67343\n",
      "\n",
      "avg / total       0.97      0.97      0.97    134686\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS Decision Tree Classifier Model Evaluation ==============================\n",
      "\n",
      "Cross Validation Mean Score:\n",
      " 0.999769836897\n",
      "\n",
      "Model Accuracy:\n",
      " 0.999948027263\n",
      "\n",
      "Confusion matrix:\n",
      " [[67343     0]\n",
      " [    7 67336]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       1.00      1.00      1.00     67343\n",
      "        1.0       1.00      1.00      1.00     67343\n",
      "\n",
      "avg / total       1.00      1.00      1.00    134686\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS KNeighborsClassifier Model Evaluation ==============================\n",
      "\n",
      "Cross Validation Mean Score:\n",
      " 0.996569816347\n",
      "\n",
      "Model Accuracy:\n",
      " 0.99775774765\n",
      "\n",
      "Confusion matrix:\n",
      " [[67287    56]\n",
      " [  246 67097]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       1.00      1.00      1.00     67343\n",
      "        1.0       1.00      1.00      1.00     67343\n",
      "\n",
      "avg / total       1.00      1.00      1.00    134686\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS LogisticRegression Model Evaluation ==============================\n",
      "\n",
      "Cross Validation Mean Score:\n",
      " 0.980822083372\n",
      "\n",
      "Model Accuracy:\n",
      " 0.980777512139\n",
      "\n",
      "Confusion matrix:\n",
      " [[65527  1816]\n",
      " [  773 66570]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.99      0.97      0.98     67343\n",
      "        1.0       0.97      0.99      0.98     67343\n",
      "\n",
      "avg / total       0.98      0.98      0.98    134686\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn import metrics\n",
    "\n",
    "models = []\n",
    "#models.append(('SVM Classifier', SVC_Classifier))\n",
    "models.append(('Naive Baye Classifier', BNB_Classifier))\n",
    "models.append(('Decision Tree Classifier', DTC_Classifier))\n",
    "#models.append(('RandomForest Classifier', RF_Classifier))\n",
    "models.append(('KNeighborsClassifier', KNN_Classifier))\n",
    "models.append(('LogisticRegression', LGR_Classifier))\n",
    "#models.append(('VotingClassifier', VotingClassifier))\n",
    "\n",
    "for i, v in models:\n",
    "    scores = cross_val_score(v, X_train, Y_train, cv=10)\n",
    "    accuracy = metrics.accuracy_score(Y_train, v.predict(X_train))\n",
    "    confusion_matrix = metrics.confusion_matrix(Y_train, v.predict(X_train))\n",
    "    classification = metrics.classification_report(Y_train, v.predict(X_train))\n",
    "    print()\n",
    "    print('============================== {} {} Model Evaluation =============================='.format(grpclass, i))\n",
    "    print()\n",
    "    print (\"Cross Validation Mean Score:\" \"\\n\", scores.mean())\n",
    "    print()\n",
    "    print (\"Model Accuracy:\" \"\\n\", accuracy)\n",
    "    print()\n",
    "    print(\"Confusion matrix:\" \"\\n\", confusion_matrix)\n",
    "    print()\n",
    "    print(\"Classification report:\" \"\\n\", classification) \n",
    "    print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test Models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "============================== Normal_DoS Naive Baye Classifier Model Test Results ==============================\n",
      "\n",
      "Model Accuracy:\n",
      " 0.833653678141\n",
      "\n",
      "Confusion matrix:\n",
      " [[5487 1971]\n",
      " [ 885 8826]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.86      0.74      0.79      7458\n",
      "        1.0       0.82      0.91      0.86      9711\n",
      "\n",
      "avg / total       0.84      0.83      0.83     17169\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS Decision Tree Classifier Model Test Results ==============================\n",
      "\n",
      "Model Accuracy:\n",
      " 0.816588036578\n",
      "\n",
      "Confusion matrix:\n",
      " [[5591 1867]\n",
      " [1282 8429]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.81      0.75      0.78      7458\n",
      "        1.0       0.82      0.87      0.84      9711\n",
      "\n",
      "avg / total       0.82      0.82      0.82     17169\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS KNeighborsClassifier Model Test Results ==============================\n",
      "\n",
      "Model Accuracy:\n",
      " 0.866620071058\n",
      "\n",
      "Confusion matrix:\n",
      " [[5787 1671]\n",
      " [ 619 9092]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.90      0.78      0.83      7458\n",
      "        1.0       0.84      0.94      0.89      9711\n",
      "\n",
      "avg / total       0.87      0.87      0.86     17169\n",
      "\n",
      "\n",
      "\n",
      "============================== Normal_DoS LogisticRegression Model Test Results ==============================\n",
      "\n",
      "Model Accuracy:\n",
      " 0.842157376667\n",
      "\n",
      "Confusion matrix:\n",
      " [[5963 1495]\n",
      " [1215 8496]]\n",
      "\n",
      "Classification report:\n",
      "              precision    recall  f1-score   support\n",
      "\n",
      "        0.0       0.83      0.80      0.81      7458\n",
      "        1.0       0.85      0.87      0.86      9711\n",
      "\n",
      "avg / total       0.84      0.84      0.84     17169\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "for i, v in models:\n",
    "    accuracy = metrics.accuracy_score(Y_test, v.predict(X_test))\n",
    "    confusion_matrix = metrics.confusion_matrix(Y_test, v.predict(X_test))\n",
    "    classification = metrics.classification_report(Y_test, v.predict(X_test))\n",
    "    print()\n",
    "    print('============================== {} {} Model Test Results =============================='.format(grpclass, i))\n",
    "    print()\n",
    "    print (\"Model Accuracy:\" \"\\n\", accuracy)\n",
    "    print()\n",
    "    print(\"Confusion matrix:\" \"\\n\", confusion_matrix)\n",
    "    print()\n",
    "    print(\"Classification report:\" \"\\n\", classification) \n",
    "    print()        \n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  },
  "latex_envs": {
   "LaTeX_envs_menu_present": true,
   "autocomplete": true,
   "bibliofile": "biblio.bib",
   "cite_by": "apalike",
   "current_citInitial": 1,
   "eqLabelWithNumbers": true,
   "eqNumInitial": 1,
   "hotkeys": {
    "equation": "Ctrl-E",
    "itemize": "Ctrl-I"
   },
   "labels_anchors": false,
   "latex_user_defs": false,
   "report_style_numbering": false,
   "user_envs_cfg": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
